import Watcher from './watcher'
class Compiler {
    constructor (vm){
        this.el = vm.$el
        this.vm = vm
        this.compile(this.el)
    }
    //编译模板，处理文本节点
    compile (el) {
        let childNodes = el.childNodes
        Array.from(childNodes).forEach( node =>{
            if(this.isTextNode(node)){
                this.compileText(node)
            } else if (this.isElementNode(node)) {
                this.compileElement(node)
            }
            //node如果有子节点，递归调用
            if(node.childNodes && node.childNodes.length){
                this.compile(node)
            }
        })
    }
    //编译元素节点，处理指令
    compileElement (node) {
        //console.log(node.attributes)
        //遍历属性节点\
        Array.from(node.attributes).forEach( attr => {
            let attrName = attr.name
            if (this.isDirective(attrName)) {
                //v-text --> text
                attrName = attrName.substr(2)
                let key = attr.value
                this.update(node, key, attrName)
            }
        })
        //判断指令
    }
    update ( node, key,attrName){
        let updateFn = this[attrName+ 'Updater']
        updateFn && updateFn.call(this, node,this.vm[key] ,key)
    }
    // 处理v-text
    textUpdater ( node, value ,key) {
        node.textContent = value
        new Watcher(this.vm,key,(newValue) =>{
            node.textContent = newValue
        })
        //
       
    }
    // 处理v-model
    modelUpdater ( node,value, key ){
        node.value = value
        new Watcher(this.vm,key,(newValue) =>{
            node.value = newValue
        })
        node.addEventListener('input', () => {
            this.vm[key] = node.value
        })
    }
    // 处理文本节点
    compileText (node) {
        //console.dir(node)

        var patt = /runoob/i
        let reg =  /\{\{(.+?)\}\}/
        let value = node.textContent
        if(reg.test(value)){
            let key = RegExp.$1.trim()
            node.textContent = value.replace(reg, this.vm[key])
            //创建watcher
            new Watcher(this.vm, key, (newValue) => {
                node.textContent = newValue
            })
        }
    }
    //是否是指令
    isDirective(attrName){
        return attrName.startsWith('v-')
    }

    isTextNode (node) {
        return node.nodeType === 3
    }

    isElementNode (node){
        return node.nodeType === 1
    }

}

export default Compiler